/* -----------------------------------------------------------------------
   See COPYRIGHT.TXT and LICENSE.TXT for copyright and license information
   ----------------------------------------------------------------------- */
#include "plm_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>

#include "bspline.h"
//#include "bspline3DT2D_optimize.h"
#include "bspline_optimize_liblbfgs.h"
#include "bspline3DT2D_optimize_lbfgsb.h"
#if (NLOPT_FOUND)
#include "bspline_optimize_nlopt.h"
#endif
#include "bspline_optimize_steepest.h"
#include "bspline_opts.h"
#include "logfile.h"
#include "math_util.h"
#include "print_and_exit.h"
#include "volume.h"
#include "xpm.h"
#include "proj_image.h"
#include "proj_image_set.h"
#include "fdk_opts.h"
#include "drr_opts.h"
#include "pvalue_optimize_lbfgsb.h"
#include "zhang_cuda.h"

static void
log_parms (Bspline_parms* parms)
{
    logfile_printf ("BSPLINE PARMS\n");
    logfile_printf ("max_its = %d\n", parms->max_its);
    logfile_printf ("max_feval = %d\n", parms->max_feval);
}

static void
log_bxf_header (Bspline_xform* bxf)
{
    logfile_printf ("BSPLINE XFORM HEADER\n");
    logfile_printf ("vox_per_rgn = %d %d %d\n", bxf->vox_per_rgn[0], bxf->vox_per_rgn[1], bxf->vox_per_rgn[2]);
    logfile_printf ("roi_offset = %d %d %d\n", bxf->roi_offset[0], bxf->roi_offset[1], bxf->roi_offset[2]);
    logfile_printf ("roi_dim = %d %d %d\n", bxf->roi_dim[0], bxf->roi_dim[1], bxf->roi_dim[2]);
}



void
pvalue_optimize (
    Bspline_xform* bxf, 
    Bspline_state **bst_in, 
    Bspline_parms *parms, 
    Volume *vol, 
	CB_Set *PSd,
    Volume *moving, 
    Volume *moving_grad,
	void * fdk_dev_state,
	void * drr_dev_state,
	Fdk_options *cb_options,
	Drr_options *drr_options)
{
    Bspline_state *bst;

    bst = bspline_state_create (bxf, parms, vol, moving, moving_grad);
    log_parms (parms);
    log_bxf_header (bxf);

 //   if (parms->metric == BMET_MI) {
	//bspline_initialize_mi (parms, fixed, moving);
 //   }

    /* Do the optimization */


    pvalue_optimize_lbfgsb(vol, PSd, parms, bst, fdk_dev_state, drr_dev_state, cb_options, drr_options);

    if (bst_in) {
	*bst_in = bst;
    } else {
	bspline_state_destroy (bst, parms, bxf, vol, moving, moving_grad);
    }
}
